package cn.imvc.app.models;

import java.awt.image.BufferedImage;
import java.io.File;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.github.sd4324530.fastweixin.api.response.GetUserInfoResponse;
import com.puff.cache.redis.Redis;

import cn.imvc.app.commons.SystemConfig;
import cn.imvc.app.domains.Constants;
import cn.imvc.app.domains.OrderType;
import cn.imvc.app.entities.Account;
import cn.imvc.app.entities.Dealer;
import cn.imvc.app.entities.DealerLevel;
import cn.imvc.app.entities.Domain;
import cn.imvc.app.entities.Member;
import cn.imvc.app.entities.Voucher;
import cn.imvc.app.entities.VoucherTemplate;
import cn.imvc.app.repositories.MemberRepository;
import cn.imvc.core.ICache;
import cn.imvc.core.Render;
import cn.imvc.util.AES;
import cn.imvc.util.DownloadImage;
import cn.imvc.util.Md5;
import cn.imvc.util.RandomId;
import cn.imvc.util.SMSVerification;
import cn.imvc.util.ToolUtils;
import cn.imvc.util.VerifyCodeUtils;

@Service
public class MemberModelImpl implements MemberModel {
	
	private Logger logger = Logger.getLogger(MemberModelImpl.class);

	@Autowired
	private MemberRepository memberRepository;

	@Autowired
	private DealerModel dealerModel;

	@Autowired
	private DomainModel domainModel;
	
	@Autowired
	private VoucherModel voucherModel;
	
	@Autowired
	private VoucherTemplateModel voucherTemplateModel;

	@Autowired
	private DealerLevelModel dealerLevelModel;

	@Autowired
	private AccountModel accountModel;

	@Autowired
	private CommissionModel commissionModel;

	@Autowired
	ICache cache;

	@Autowired
	SystemConfig systemConfig;

	@Autowired
	SMSVerification smsVerification;

	@Autowired
	SMSModel smsModel;

	@Autowired
	SendMailModel sendMailModel;
	
	@Autowired
	MessageModel messageModel;

	public Member get(int id) {
		return memberRepository.findOne(id);
	}

	public Member getByLoginname(String loginname) {
		List<Member> members = memberRepository.findByLoginname(loginname);
		if (members != null && members.size() == 1) {
			return members.get(0);
		} else {
			return null;
		}
	}

	public Map<String, String> saveRegister(Member register, String messagecode, String domain, String serverName) {
		Map<String, String> result = new HashMap<String, String>();
		result.put("code", "0");
		if (StringUtils.isEmpty(register.getLoginname())) {
			result.put("msg", "手机号不能为空");
		} else if (!ToolUtils.isMobile(register.getLoginname())) {
			result.put("msg", "手机号格式不正确");
		} else if (StringUtils.isEmpty(register.getPasswd())) {
			result.put("msg", "密码不能为空");
		} else if (StringUtils.isEmpty(messagecode)) {
			result.put("msg", "短信验证码不能为空");
		} else {
			if (checkCodeError(register.getLoginname())) {
				if (checkMessageCode(messagecode, register.getLoginname())) {
					result = saveRegister(register, serverName, domain);
					String code = result.get("code");
					if("1".equals(code)){
						cache.remove(Constants.CACHENAME_MEMBER, Constants.MESSAGE_CODE_KEY_PREFIX + register.getLoginname());
						register = getByLoginname(register.getLoginname());
						String token = Md5.encode(register.getLoginname() + String.valueOf(System.currentTimeMillis()));
						updateLoginMember(register, token);
						result.put("token", token);
						result.put("domain", Constants.DOMAIN_PREFIX + register.getId() + Constants.DOMAIN_SUFFIX);
						result.put("suffix", Constants.DOMAIN_SUFFIX);
					}
				} else {
					result.put("msg", "短信验证码不正确");
				}
			} else {
				result.put("msg", "系统繁忙，请稍后再试");
			}
		}
		return result;
	}
	
	public Map<String, String> savePcRegister(Member register, String messagecode, String imagecode, String serverName, String key) {
		Map<String, String> result = new HashMap<String, String>();
		result.put("code", "0");
		if (StringUtils.isEmpty(register.getLoginname())) {
			result.put("msg", "手机号不能为空");
		} else if (!ToolUtils.isMobile(register.getLoginname())) {
			result.put("msg", "手机号格式不正确");
		} else if (StringUtils.isEmpty(messagecode)) {
			result.put("msg", "短信验证码不能为空");
		} else if (StringUtils.isEmpty(register.getPasswd())) {
			result.put("msg", "密码不能为空");
		} else {
			if (checkCodeError(register.getLoginname())) {
				if (checkMessageCode(messagecode, register.getLoginname())) {
					result = saveRegister(register, serverName, null);
					String code = result.get("code");
					if("1".equals(code)){
						cache.remove(Constants.CACHENAME_MEMBER, Constants.MESSAGE_CODE_KEY_PREFIX + register.getLoginname());
						register = getByLoginname(register.getLoginname());
						String token = Md5.encode(register.getLoginname() + String.valueOf(System.currentTimeMillis()));
						updateLoginMember(register, token);
						result.put("token", token);
						result.put("domain", Constants.DOMAIN_PREFIX + register.getId() + Constants.DOMAIN_SUFFIX);
						result.put("suffix", Constants.DOMAIN_SUFFIX);
					}
				} else {
					result.put("msg", "短信验证码不正确");
				}
			} else {
				result.put("msg", "系统繁忙，请稍后再试");
			}
		}
		return result;
	}
	
	private Map<String, String> saveRegister(Member register, String serverName, String domain){
		Map<String, String> result = new HashMap<String, String>();
		String key2 = Md5.encode(String.valueOf(System.currentTimeMillis()));
		Member member = getByLoginname(register.getLoginname());
		if (member == null) {
			member = new Member();
			member.setLoginname(register.getLoginname());
			member.setKey1(register.getKey1());
			member.setKey2(key2);
			member.setPasswd(Md5.encode(register.getPasswd() + key2));
			member.setMobile(register.getLoginname());
			member.setTime(new Timestamp(System.currentTimeMillis()));
			member.setState((byte) 1);
			member = memberRepository.saveAndFlush(member);
			// 注册时根据域名123.xinghao.com取父节点id，如果没有上级，默认guid为自身id
			// 如果有上级，guid为上级的guid拼上(,自身id)
			if(!StringUtils.isEmpty(domain) && !"undefined".equals(domain)){
				Dealer dealer = dealerModel.getByDomain(domain);
				if(dealer != null){
					Member parent = dealer.getMember();
					if (parent == null) {
						member.setGuid(String.valueOf(member.getId()));
					} else {
						member.setGuid(parent.getGuid() + "," + String.valueOf(member.getId()));
						member.setParent(parent);
					}
				} else {
					member.setGuid(String.valueOf(member.getId()));
				}
			} else {
				String[] www = serverName.split("\\.");
				if(www.length == 3){
					List<Domain> list = domainModel.getByDomain(www[0]);
					if(list != null && list.size() == 1) {
						Domain dom = list.get(0);
						int parentid = dom.getMemberId();
						Member parent = memberRepository.getOne(parentid);
						if (parent == null) {
							member.setGuid(String.valueOf(member.getId()));
						} else {
							member.setGuid(parent.getGuid() + "," + String.valueOf(member.getId()));
							member.setParent(parent);
						}
					} else {
						member.setGuid(String.valueOf(member.getId()));
					}
				} else {
					member.setGuid(String.valueOf(member.getId()));
				}
			}
			member.setName(register.getLoginname());
			saveRegister(member);
			result.put("code", "1");
			result.put("msg", "注册成功");
		} else {
			result.put("msg", "用户已存在");
		}
		return result;
	}

	public Member save(Member member) {
		return memberRepository.saveAndFlush(member);
	}

	public Member update(Member newMember) {
		Member loadMember = get(newMember.getId());
		BeanUtils.copyProperties(newMember, loadMember, new String[] { "id", "created_at", "updated_at" });
		return memberRepository.saveAndFlush(loadMember);
	}

	public void delete(int id) {
		memberRepository.delete(id);

	}

	public void deleteBatch(int[] ids) {
		for (int id : ids) {
			delete(id);
		}
	}

	public Map<String, Object> checkLoginSubmit(Member login) {
		Map<String, Object> result = new HashMap<String, Object>();
		result.put("code", "0");
		if (StringUtils.isEmpty(login.getLoginname())) {
			result.put("msg", "用户名不能为空");
		} else if (StringUtils.isEmpty(login.getPasswd())) {
			result.put("msg", "密码不能为空");
		}
		Member member = getByLoginname(login.getLoginname());
		if (member != null) {
			member = get(member.getId());
			String key2 = member.getKey2();
			String passwd = member.getPasswd();
			if (passwd.equals(Md5.encode(login.getPasswd() + key2))) {
				result.put("code", "1");
				String token = Md5.encode(login.getLoginname() + String.valueOf(System.currentTimeMillis()));
				updateLoginMember(member, token);
				result.put("token", token);
				result.put("domain", Constants.DOMAIN_PREFIX + member.getDealer().getDomain() + Constants.DOMAIN_SUFFIX);
				result.put("suffix", Constants.DOMAIN_SUFFIX);
			} else {
				result.put("msg", "密码不正确");
			}
		} else {
			result.put("msg", "用户不存在");
		}
		return result;
	}

	public void updateLoginMember(Member member, String token) {
		cache.put(Constants.CACHENAME_MEMBER, token, member, Constants.TOKEN_INDATE);
	}

	public void removeLoginMember(String token) {
		cache.remove(Constants.CACHENAME_MEMBER, token);
	}

	public Member getLoginMember(String token) {
		if (StringUtils.isEmpty(token) || "undefined".equalsIgnoreCase(token)) {
			return null;
		}
		Member member = cache.get(Constants.CACHENAME_MEMBER, token);
		if (member == null) {
			return null;
		} else {
			updateLoginMember(member, token);
			return member;
		}
	}

	public boolean checkLogin(String token) {
		if (getLoginMember(token) == null) {
			return false;
		} else {
			return true;
		}
	}

	public boolean checkCodeError(String mobile) {
		Integer times = cache.get(Constants.CACHENAME_MEMBER, "CODE_ERROR_TIMES_" + mobile);
		if(times != null && times >= smsVerification.getCodeErrorTimes()){
			return false;
		} else {
			return true;
		}
	}

	public boolean checkMessageCode(String code, String mobile) {
		String cachecode = cache.get(Constants.CACHENAME_MEMBER, Constants.MESSAGE_CODE_KEY_PREFIX + mobile);
		if (code.equalsIgnoreCase(cachecode)) {
			return true;
		} else {
			Integer times = cache.get(Constants.CACHENAME_MEMBER, "CODE_ERROR_TIMES_" + mobile);
			if(times != null){
				cache.update(Constants.CACHENAME_MEMBER, "CODE_ERROR_TIMES_" + mobile, times + 1);
			} else {
				cache.put(Constants.CACHENAME_MEMBER, "CODE_ERROR_TIMES_" + mobile, 1, smsVerification.getMobileLater());
			}
			return false;
		}
	}

	public boolean checkImageCode(String code, String key) {
		String cachecode = cache.get("IMG_CODE", key);
		if (code.equalsIgnoreCase(cachecode)) {
			return true;
		} else {
			return false;
		}
	}

	public boolean checkEmailCode(String code, String email) {
		String cachecode = cache.get(Constants.CACHENAME_MEMBER, Constants.EMAIL_CODE_KEY_PREFIX + email);
		if (code.equalsIgnoreCase(cachecode)) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 注册成功后保存dealer
	 * 
	 * @param member
	 * @return
	 */
	private Dealer saveDealer(Member member) {
		Dealer dealer = new Dealer();
		dealer.setMember(member);
		dealer.setName(member.getName());
		dealer.setDomain(String.valueOf(member.getId()));
		dealer.setCreatedAt(new Date());
		DealerLevel dealerLevel = dealerLevelModel.findMinDealerLevel();
		dealer.setDealerLevel(dealerLevel);
		return dealerModel.save(dealer);
	}

	/**
	 * 注册成功后保存domain
	 * 判断domain是否存在，如果存在，则在id后面依次拼接abc等，直到domain唯一为止
	 * @param member
	 * @return
	 */
	private Domain saveDomain(Member member) {
		Domain domain = new Domain();
		domain.setMemberId(member.getId());
		List<Domain> list = domainModel.getByDomain(String.valueOf(member.getId()));
		if(list != null && list.size() > 0){
			for (int i = 0; i < ToolUtils.strs.length; i++){
				list = domainModel.getByDomain(String.valueOf(member.getId()) + ToolUtils.strs[i]);
				if(list == null || (list != null && list.size() == 1)){
					domain.setDomain(String.valueOf(member.getId()) + ToolUtils.strs[i]);
					break;
				}
			}
		} else {
			domain.setDomain(String.valueOf(member.getId()));
		}
		return domainModel.save(domain);
	}

	/**
	 * 注册成功后保存account
	 * 
	 * @param member
	 * @return
	 */
	private Account saveAccount(Member member) {
		Account account = new Account();
		account.setMember(member);
		account.setPurse(0);
		account.setCommissions(0);
		account.setPoints(0);
		account.setState((byte) 1);
		account.setVersion(1);
		account.setIsLocked((byte) 0);
		account.setKey1(Md5.encode(String.valueOf(System.currentTimeMillis())));
		String content = "0,0,0";
		account.setVerify(AES.encrypt(content, systemConfig.getAESPassword()));
		return accountModel.save(account);
	}
	/**
	 * 注册成功后添加代金券
	 * 
	 * @param member
	 * @return
	 */

	private Voucher saveVoucher(Member member) {
		VoucherTemplate voucherTemplate=voucherTemplateModel.findByCode("REGISTER");
		if (voucherTemplate==null||voucherTemplate.getTotal()<=voucherTemplate.getGiveout())
			return null;
		voucherTemplate.setGiveout(voucherTemplate.getGiveout()+1);
		voucherTemplateModel.save(voucherTemplate);
		
		Voucher voucher=new Voucher();
		voucher.setVoucherTemplate(voucherTemplate);
		voucher.setMember(member);
		voucher.setName(voucherTemplate.getName());
		voucher.setCode(OrderType.Voucher.getValue()+RandomId.randomId(new Date().getTime()));
		voucher.setDescription(voucherTemplate.getDescription());
		voucher.setGoodsBrand(voucherTemplate.getGoodsBrand());
		voucher.setGoodsBrandName(voucherTemplate.getGoodsBrandName());
		voucher.setGoodsClass(voucherTemplate.getGoodsClass());
		voucher.setGoodsClassName(voucherTemplate.getGoodsClassName());
		voucher.setGoodsType(voucherTemplate.getGoodsType());
		voucher.setGoodsTypeName(voucherTemplate.getGoodsTypeName());
		voucher.setStartDate(voucherTemplate.getStartDate()==null?new Date():voucherTemplate.getStartDate());
		voucher.setEndDate(new DateTime(voucher.getStartDate()).plusDays(voucherTemplate.getTimeLimit()).toDate());
		voucher.setPrice(voucherTemplate.getPrice());
		voucher.setLimitMoney(voucherTemplate.getLimitMoney());
		voucher.setState((byte)0);
		String content=voucher.getGoodsBrand()+";"+voucher.getGoodsClass()+";"+voucher.getGoodsType();
		voucher.setVerify(AES.encrypt(content, systemConfig.getAESPassword()));
		return voucherModel.save(voucher);
	}

	public Map<String, String> checkLoginname(String loginname) {
		Map<String, String> result = new HashMap<String, String>();
		if (StringUtils.isEmpty(loginname)) {
			result.put("code", "0");
			result.put("msg", "用户名不能为空");
		} else {
			Member member1 = getByLoginname(loginname);
			if (member1 == null) {
				result.put("code", "0");
				result.put("msg", "用户不存在");
			} else if(member1.getState() == (byte)0){
				result.put("code", "0");
				result.put("msg", "用户被禁用");
			} else {
				result.put("code", "1");
				result.put("key1", member1.getKey1());
			}
		}
		return result;
	}

	public Map<String, String> sendMessageCode(String mobile, String imagecode, String ip, String key) {
		Map<String, String> result = new HashMap<String, String>();
		// 同一个手机号短信验证码错误达到一定频率，此号码禁用一定时间
		Integer ipTimes = cache.get(Constants.CACHENAME_MEMBER, "IP_TIMES_" + ip);
		if(cache.get(Constants.CACHENAME_MEMBER, "CODE_ERROR_TIMES_" + mobile) != null){
			result.put("code", "0");
			result.put("msg", "系统异常，请稍后再试");
			if(ipTimes != null && ipTimes >= smsVerification.getIpTimes()){
				result.put("showImageCode", "1");
			} else {
				result.put("showImageCode", "0");
			}
			return result;
		}
		// 同一个ip发送短信验证码达到一定频率，显示图形验证码
		if(ipTimes != null && ipTimes >= smsVerification.getIpTimes()){
			if(StringUtils.isEmpty(imagecode)){
				result.put("code", "0");
				result.put("msg", "图形验证码不能为空");
				result.put("showImageCode", "1");
				return result;
			} else if(!checkImageCode(imagecode, key)){
				result.put("showImageCode", "1");
				result.put("code", "0");
				result.put("msg", "图形验证码错误");
				return result;
			}
		}
		int cachetime = cache.ttl(Constants.CACHENAME_MEMBER, Constants.MESSAGE_CODE_KEY_PREFIX + mobile);
		int safety = Constants.MESSAGE_CODE_INDATE - Constants.MESSAGE_CODE_INTERVAL;
		if (cachetime < safety) {
			result.put("code", "0");
			String code = ToolUtils.getRandomNumber(6);
			Map<String, String> sendResult = smsModel.sendMessageCode(mobile, code);
			if ("1".equals(sendResult.get("code"))) {
				if(ipTimes != null && ipTimes >= smsVerification.getIpTimes()){
					cache.remove("IMG_CODE", key);
				}
				cache.put(Constants.CACHENAME_MEMBER, Constants.MESSAGE_CODE_KEY_PREFIX + mobile, code, Constants.MESSAGE_CODE_INDATE);
				Integer times = cache.get(Constants.CACHENAME_MEMBER, "IP_TIMES_" + ip);
				// 每天前N次发短信不需要验证码
				if(times == null || (times != null && times == 0)){
					cache.put(Constants.CACHENAME_MEMBER, "IP_TIMES_" + ip, 1, ToolUtils.getLeftMillis());
				} else {
					cache.update(Constants.CACHENAME_MEMBER, "IP_TIMES_" + ip, times + 1);
				}
				result.put("code", "1");
				result.put("msg", "发送成功");
			} else {
				result.put("msg", sendResult.get("msg"));
			}
		} else {
			int remain = cachetime - safety;
			result.put("code", "-2");
			result.put("second", String.valueOf(remain));
			result.put("msg", "间隔太短，请于" + remain + "秒后重新获取");
		}
		Integer times = cache.get(Constants.CACHENAME_MEMBER, "IP_TIMES_" + ip);
		if(times != null && times >= smsVerification.getIpTimes()){
			result.put("showImageCode", "1");
		} else {
			result.put("showImageCode", "0");
		}
		return result;
	}

	public Map<String, String> sendMessageCode(String mobile) {
		Map<String, String> result = new HashMap<String, String>();
		int cachetime = cache.ttl(Constants.CACHENAME_MEMBER, Constants.MESSAGE_CODE_KEY_PREFIX + mobile);
		int safety = Constants.MESSAGE_CODE_INDATE - Constants.MESSAGE_CODE_INTERVAL;
		if (cachetime < safety) {
			result.put("code", "0");
			String code = ToolUtils.getRandomNumber(6);
			Map<String, String> sendResult = smsModel.sendMessageCode(mobile, code);
			if ("1".equals(sendResult.get("code"))) {
				cache.put(Constants.CACHENAME_MEMBER, Constants.MESSAGE_CODE_KEY_PREFIX + mobile, code, Constants.MESSAGE_CODE_INDATE);
				result.put("code", "1");
				result.put("msg", "发送成功");
			} else {
				result.put("msg", sendResult.get("msg"));
			}
		} else {
			int remain = cachetime - safety;
			result.put("code", "-2");
			result.put("second", String.valueOf(remain));
			result.put("msg", "间隔太短，请于" + remain + "秒后重新获取");
		}
		return result;
	}

	public Map<String, String> sendEmailCode(String email) {
		Map<String, String> result = new HashMap<String, String>();
		String code = ToolUtils.getRandomNumber(6);
		String content = "尊敬的会员，您的验证码为" + code + "，十分钟内有效。如非本人操作，请忽略此邮件。";
		Map<String, String> sendResult = sendMailModel.sendEmail(email, "【星昊商城】修改会员账户信息", content);
		if ("1".equals(sendResult.get("code"))) {
			cache.put(Constants.CACHENAME_MEMBER, Constants.EMAIL_CODE_KEY_PREFIX + email, code, Constants.MESSAGE_CODE_INDATE);
			result.put("code", "1");
			result.put("msg", "发送成功");
		} else {
			result.put("msg", "发送失败");
		}
		return result;
	}

	public Map<String, String> sendCode(String loginname) {
		Map<String, String> result = new HashMap<String, String>();
		result.put("code", "0");
		if (!StringUtils.isEmpty(loginname)) {
			if (loginname.indexOf("@") > -1) {
				if(!ToolUtils.isEmail(loginname)){
					result.put("msg", "邮箱地址格式不正确");
					return result;
				}
				return sendEmailCode(loginname);
			} else {
				if(!ToolUtils.isMobile(loginname)){
					result.put("msg", "手机号格式不正确");
					return result;
				}
				return sendMessageCode(loginname);
			}
		} else {
			result.put("msg", "手机号或邮箱不能为空");
			return result;
		}
	}

	public Map<String, String> sendCode(String loginname, String imagecode, String ip, String key) {
		Map<String, String> result = new HashMap<String, String>();
		result.put("code", "0");
		if (!StringUtils.isEmpty(loginname)) {
			if (loginname.indexOf("@") > -1) {
				if(!ToolUtils.isEmail(loginname)){
					result.put("msg", "邮箱地址格式不正确");
					return result;
				}
				return sendEmailCode(loginname);
			} else {
				if(!ToolUtils.isMobile(loginname)){
					result.put("msg", "手机号格式不正确");
					return result;
				}
				return sendMessageCode(loginname, imagecode, ip, key);
			}
		} else {
			result.put("msg", "手机号或邮箱不能为空");
			return result;
		}
	}

	public Map<String, String> checkMCodeForKey(String mobile, String messagecode) {
		Map<String, String> result = new HashMap<String, String>();
		result.put("code", "0");
		if (StringUtils.isEmpty(mobile)) {
			result.put("msg", "手机号不能为空");
		} else if (!ToolUtils.isMobile(mobile)) {
			result.put("msg", "手机号格式不正确");
		} else {
			Member member = getByLoginname(mobile);
			if (member == null) {
				result.put("msg", "用户不存在");
			} else {
				if (StringUtils.isEmpty(messagecode)){
					result.put("msg", "验证码不能为空");
				} else if (!checkCodeError(mobile)){
					result.put("msg", "系统繁忙，请稍后再试");
				} else if (checkMessageCode(messagecode, mobile)) {
					result.put("key1", member.getKey1());
					result.put("code", "1");
					cache.remove(Constants.CACHENAME_MEMBER, Constants.MESSAGE_CODE_KEY_PREFIX + mobile);
				} else {
					result.put("msg", "验证码不正确");
				}
			}
		}
		return result;
	}

	public Map<String, String> saveResetPasswd(String loginname, String passwd, String key1) {
		Map<String, String> result = new HashMap<String, String>();
		result.put("code", "0");
		if (StringUtils.isEmpty(loginname)) {
			result.put("msg", "用户名不能为空");
		} else if (StringUtils.isEmpty(passwd)) {
			result.put("msg", "密码不能为空");
		} else if (StringUtils.isEmpty(key1)) {
			result.put("msg", "系统异常，请稍后再试！");
			logger.error("忘记密码：" + loginname + "，key1为空，result:" + Render.json(result));
		} else {
			Member member = getByLoginname(loginname);
			if (member != null) {
				if(!key1.equals(member.getKey1())){
					result.put("msg", "您没有权限操作！");
				} else {
					member.setPasswd(Md5.encode(passwd + member.getKey2()));
					memberRepository.saveAndFlush(member);
					result.put("code", "1");
					result.put("msg", "密码修改成功");
				}
			} else {
				result.put("msg", "用户不存在");
			}
		}
		return result;
	}
	
	public List<Member> findByEmail(String email){
		return memberRepository.findByEmail(email);
	}
	
	public Member findByUnionid(String unionid){
		List<Member> list = memberRepository.findByUnionid(unionid);
		if(list != null && list.size() == 1){
			return list.get(0);
		}
		return null;
	}
	
	public Member findByQqOpenid(String qqOpenid){
		List<Member> list = memberRepository.findByQqOpenid(qqOpenid);
		if(list != null && list.size() == 1){
			return list.get(0);
		}
		return null;
	}

	public Map<String, String> saveRegLoginSubmit(String mobile, String  code, String wxOpenid, GetUserInfoResponse userInfoResponse, String type, String domain, String serverName) {
		Map<String, String> result = new HashMap<String, String>();
		result.put("code", "0");
		if (StringUtils.isEmpty(mobile)) {
			result.put("msg", "手机号不能为空");
		} else if (!ToolUtils.isMobile(mobile)) {
			result.put("msg", "手机号格式不正确");
		} else if (StringUtils.isEmpty(code)) {
			result.put("msg", "验证码为空");
		} else {
			if (checkCodeError(mobile)) {
				if (checkMessageCode(code, mobile)) {
					Member member = getByLoginname(mobile);
					if(member == null){ 
						//使用全局锁
						if (!(Redis.getInstance().setnx("register"+mobile, "aa") == 1)){//如果没有获得锁，说明是重复注册，直接返回。
							result.put("msg", "系统正在处理中，请勿重复操作！");
							return result;
						}
						//5分钟过期，若程序出现异常，5分钟后该手机号可以再次注册。
						Redis.getInstance().expire("register"+mobile, 5*60);
						member = new Member();
						member.setLoginname(mobile);
						member.setMobile(mobile);
						String times = String.valueOf(System.currentTimeMillis());
						member.setKey1(Md5.encode(times));
						String passwd = ToolUtils.getRandomNumber(6);
						times = String.valueOf(System.currentTimeMillis());
						member.setKey2(Md5.encode(times));
						member.setPasswd(Md5.encode(Md5.encode(passwd + member.getKey1()) + member.getKey2()));
						member.setTime(new Timestamp(System.currentTimeMillis()));
						member.setState((byte) 1);
						member = save(member);
						Member parent = null;
						if(!StringUtils.isEmpty(wxOpenid)){
							member.setWxOpenid(wxOpenid);
							parent = cache.get("SCAN", wxOpenid);
						}
						if(parent != null){
							member.setParent(parent);
							member.setGuid(parent.getGuid() + "," + String.valueOf(member.getId()));
						} else {
							if (!StringUtils.isEmpty(domain) && !"undefined".equals(domain)) {
								Dealer dealer = dealerModel.getByDomain(domain);
								if (dealer != null) {
									parent = dealer.getMember();
									member.setParent(parent);
									member.setGuid(parent.getGuid() + "," + String.valueOf(member.getId()));
								} else {
									if(!StringUtils.isEmpty(serverName)){
										String[] www = serverName.split("\\.");
										if(www.length == 3 && !"www".equals(www[0])){
											dealer = dealerModel.getByDomain(domain);
											if (dealer != null) {
												parent = dealer.getMember();
												member.setParent(parent);
												member.setGuid(parent.getGuid() + "," + String.valueOf(member.getId()));
											} else {
												member.setGuid(String.valueOf(member.getId()));
											}
										}
									} else {
										member.setGuid(String.valueOf(member.getId()));
									}
								}
							} else {
								member.setGuid(String.valueOf(member.getId()));
							}
						}
						if(StringUtils.isEmpty(type) || "open".equals(type)){
							member = setWeiXinParam(member, userInfoResponse, false);
						} else if ("qq".equals(type)) {
							member = setQQParam(member, userInfoResponse, false);
						}
						saveRegister(member);
						smsModel.sendMessagePasswd(mobile, passwd);
						cache.remove("SCAN", wxOpenid);
						//解除锁
						Redis.getInstance().remove("register"+mobile);
					} else {
						if(StringUtils.isEmpty(type) || "open".equals(type)){
							if(StringUtils.isEmpty(member.getUnionid())){
								member.setWxOpenid(wxOpenid);
								member = setWeiXinParam(member, userInfoResponse, true);
							} else {
								result.put("msg", "手机号已存在");
								return result;
							}
						} else if ("qq".equals(type)) {
							if(StringUtils.isEmpty(member.getQqOpenid())){
								member = setQQParam(member, userInfoResponse, true);
							} else {
								result.put("msg", "手机号已存在");
								return result;
							}
						}
						save(member);
					}
					String token = Md5.encode(mobile + String.valueOf(System.currentTimeMillis()));
					updateLoginMember(member, token);
					result.put("token", token);
					result.put("code", "1");
					String domainUrl = Constants.DOMAIN;
					if(member.getDealer() != null){
						String dealer_domain = member.getDealer().getDomain();
						if(StringUtils.isEmpty(dealer_domain)){
							dealer_domain = "www";
						}
						domainUrl = Constants.DOMAIN_PREFIX + dealer_domain + Constants.DOMAIN_SUFFIX;
					}
					result.put("domain", domainUrl);
					cache.remove(Constants.CACHENAME_MEMBER, Constants.MESSAGE_CODE_KEY_PREFIX + mobile);
				} else {
					result.put("msg", "验证码不正确");
				}
			} else {
				result.put("msg", "系统繁忙，请稍后再试");
			}
		}
		return result;
	}
	
	/**
	 * 
	 * @param member
	 * @param userInfoResponse
	 * @param isExists member是否存在
	 * @return
	 */
	private Member setWeiXinParam(Member member, GetUserInfoResponse userInfoResponse, boolean isExists){
		if(userInfoResponse != null){
			if(!isExists) {
				saveUserInfoResponse(member, userInfoResponse);
			}
			member.setUnionid(userInfoResponse.getUnionid());
		}
		return member;
	}
	
	private Member setQQParam(Member member, GetUserInfoResponse userInfoResponse, boolean isExists){
		if(userInfoResponse != null){
			if(!isExists) {
				saveUserInfoResponse(member, userInfoResponse);
			}
			member.setQqOpenid(userInfoResponse.getUnionid());
		}
		return member;
	}
	
	private Member saveUserInfoResponse(Member member, GetUserInfoResponse userInfoResponse){
		if(StringUtils.isEmpty(member.getName())){
			member.setName(userInfoResponse.getNickname());
			Dealer dealer = dealerModel.findByMember(member);
			if(dealer != null){
				dealer.setName(userInfoResponse.getNickname());
				dealerModel.save(dealer);
			}
		}
		if(StringUtils.isEmpty(member.getAvatar())){
			String himg = userInfoResponse.getHeadimgurl();
			if(!StringUtils.isEmpty(himg)){
				String filename = Md5.encode(String.valueOf(System.currentTimeMillis())) + ".jpg";
				String savePath = systemConfig.getImagePath() + systemConfig.getUserImageFolder() + File.separator + ToolUtils.getDateFormat(new Date(), "yyyyMMdd");
				try {
					DownloadImage.download(userInfoResponse.getHeadimgurl(), filename, savePath);
					savePath = savePath.replace(systemConfig.getImagePath(), systemConfig.getImageDomain()) + File.separator + filename;
					savePath = savePath.replace(File.separator, "/");
					member.setAvatar(savePath);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		return member;
	}
	
	private Member saveRegister(Member member){
		member = save(member);
		saveDomain(member);
		saveDealer(member);
		saveAccount(member);
		saveVoucher(member);
		try{
		newMember(member);
		}catch(Exception e){
			e.printStackTrace();
		}
		Member parent = member.getParent();
		if(parent != null){
			parent = get(parent.getId());
			List<Member> children = findByParent(parent);
			// 直接下线人数达到100时会员自动升级为分销商
			if (children != null) {
				if (children.size() >= 100 && parent.getDealer().getDealerLevel().getLevel() == 1) {
					DealerLevel dealerLevel = dealerLevelModel.findByLevel(2);
					Dealer dealer = parent.getDealer();
					dealer.setDealerLevel(dealerLevel);
					dealerModel.save(dealer);
				}
			}
			// 每推荐一个会员，推荐人身份是普通会员分到10积分，身份是普通会员以上分到20积分
			if(parent.getDealer().getDealerLevel().getType() == (byte)0){
				commissionModel.addPointsCommission(parent, (byte)20, 10, member);
			} else {
				commissionModel.addPointsCommission(parent, (byte)20, 20, member);
			}
		}
		return member;
	}
	
	public BufferedImage getImageCode(String key){
		try {
			Map<String, Object> result = VerifyCodeUtils.createImageCode();
			cache.put("IMG_CODE", key, String.valueOf(result.get("code")), Constants.MESSAGE_CODE_INDATE);
			return (BufferedImage)result.get("img");
		} catch (Exception e) {
			e.printStackTrace();
			logger.info("获取图形验证码失败", e);
		}
		return null;
	}

	public Map<String, String> checkRegisterLoginname(String loginname) {
		Map<String, String> result = new HashMap<String, String>();
		Member member = getByLoginname(loginname);
		if(member == null){
			result.put("code", "1");
		} else {
			result.put("code", "0");
			result.put("msg", "账户已存在");
		}
		return result;
	}
	
	public void newMember(Member member) throws Exception{
		Member oldMember = 	member;
		int s=1;
		while(member.getParent()!=null&&s<5){
			member=member.getParent();
			int level=member.getDealer().getDealerLevel().getLevel();
			if(level<s){
				continue;
			}
			s=level;
			s++;
			List<String> list=new ArrayList<String>();
			list.add(member.getName());
			if(member.getId()==oldMember.getParent().getId()){
				if(member.getDealer().getDealerLevel().getType() == (byte)0){
				  list.add(oldMember.getName()+",并获得了10积分");		
				}else{
				  list.add(oldMember.getName()+",并获得了20积分");		
				}
				
			}else{
				list.add(oldMember.getName());	
			}
			
			messageModel.sendMessage(member, "newMember", list);
		}
	}
	
	public List<Member> findByParent(Member parent){
		return memberRepository.findByParentId(parent.getId());
	}
	
	public void checkTokenForApp(String token, String app){
		Member member = getLoginMember(token);
		if(member != null && !StringUtils.isEmpty(app)) {
			member.setApp(app);
			save(member);
		}
	}

}